<template>
  <div>
    <!-- 查找添加 -->
    <el-space>
      <el-select placeholder="请选择广告状态" v-model="selectParameter.status">
        <el-option
          v-for="item in adStatusMap"
          :label="item.name"
          :value="item.value"
          :key="item.value"
        />
      </el-select>
      <el-select placeholder="请选择广告类型" v-model="selectParameter.type">
        <el-option
          v-for="item in adTypeMap"
          :label="item.name"
          :value="item.value"
          :key="item.value"
        />
      </el-select>
      <el-button type="primary" :icon="Search" @click="seekData">查找</el-button>
      <el-button type="primary" :icon="Plus" @click="addAdvertising">添加</el-button>
    </el-space>
    <!-- 广告管理 -->
    <el-table :data="advertisingData" border style="width: 100%" v-loading="loading">
      <el-table-column prop="id" label="广告ID" align="center" />
      <el-table-column prop="title" label="广告标题" align="center" />
      <el-table-column prop="imgUrl" label="广告图片" align="center">
        <template #default="scope">
          <el-tag
            class="ml-2"
            type="info"
            v-if="scope.row.imgUrl=='https://www.baidu.com/img/flexible/logo/pc/result.png'"
          >类型无需图片</el-tag>
          <el-popover trigger="hover" placement="right" v-else>
            <template #reference>
              <el-image :src="scope.row.imgUrl" />
            </template>
            <el-image :src="scope.row.imgUrl" style="max-height: 100px; max-width: 150px" />
          </el-popover>
        </template>
      </el-table-column>
      <el-table-column prop="type" label="广告类型" align="center">
        <template #default="scope">
          <el-tag>{{advertisingTypes(scope.row.type)}}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="广告状态" align="center">
        <template #default="scope">
          <el-tag
            class="ml-2"
            :type="scope.row.status==1?'success':'danger'"
          >{{scope.row.status==1?"激活":"冻结"}}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="unionType" label="关联类型" align="center">
        <template #default="scope">
          <el-tag type="warning">{{associationTypes(scope.row.unionType)}}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="unionValue" label="关联值[ID]" align="center" width="230px" />
      <el-table-column prop="gmtCreate" label="创建时间" align="center">
        <template #default="scope">{{ new Date(scope.row.gmtCreate).followTime() }}</template>
      </el-table-column>
      <el-table-column label="操作" align="center">
        <template #default="scope">
          <el-button type="primary" @click="handleRedact(scope.row)">编辑</el-button>
          <el-button type="danger" @click="handleDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 对话框 -->
    <el-dialog v-model="dialogVisible" :title="title" width="30%" :before-close="handleClose">
      <el-form
        ref="ruleFormRef"
        :model="ruleForm"
        :rules="rules"
        label-width="80px"
        class="demo-ruleForm"
      >
        <el-form-item label="广告标题" prop="title">
          <el-input v-model="ruleForm.title" />
        </el-form-item>
        <el-form-item label="广告类型" prop="type" v-bind="imgShow">
          <el-select placeholder="请选择" v-model="ruleForm.type">
            <el-option
              v-for="item in adTypeMap"
              :label="item.name"
              :value="item.value"
              :key="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="广告图片" v-if="imgShow" :style="'background-color:' + ruleForm.color">
          <el-upload
            ref="elimiNate"
            action="http://192.168.1.188:8080/upload/admin"
            list-type="picture-card"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
            :headers="token"
            :limit="1"
          >
            <canvas v-show="false" ref="canvas" />
            <template #default v-if="title=='编辑'&&imgUrl">
              <el-image :src="imgUrl" />
            </template>
          </el-upload>
        </el-form-item>
        <el-form-item label="广告状态" prop="status">
          <el-switch v-model="ruleForm.status" :active-value="1" :inactive-value="0" />
        </el-form-item>
        <el-form-item label="关联类型" prop="unionType">
          <el-select
            placeholder="请选择广告类型"
            v-model="ruleForm.unionType"
            @change="ruleForm.unionValue=''"
          >
            <el-option
              v-for="item in adUnionTypeMap"
              :label="item.name"
              :value="item.value"
              :key="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="商品" prop="unionValue" v-if="ruleForm.unionType==1">
          <el-cascader :options="option" :props="props" v-model="ruleForm.unionValue" />
        </el-form-item>
        <el-form-item label="类目" prop="unionValue" v-if="ruleForm.unionType==2">
          <el-cascader :options="options" :props="props" v-model="ruleForm.unionValue" />
        </el-form-item>
        <el-form-item label="关键字" prop="unionValue" v-if="ruleForm.unionType==3">
          <el-input v-model="ruleForm.unionValue" placeholder="点击广告后，用户将得到此关键字的商品" clearable />
        </el-form-item>
        <el-form-item label="功能页面" prop="unionValue" v-if="ruleForm.unionType==4">
          <el-select placeholder="请选择一个功能页面" v-model="ruleForm.unionValue">
            <el-option
              v-for="item in functionPages"
              :label="item.name"
              :value="item.value"
              :key="item.value"
            />
          </el-select>
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleClose">取消</el-button>
          <el-button
            type="primary"
            @click="title=='创建'?keepAdvertising('ruleFormRef'):redactdvertising('ruleFormRef')"
          >确定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 分页 -->
    <pa-ging v-bind="pages" @changePage="changePage" @changeLimit="changeLimit" />
  </div>
</template>

<script>
import { Search, Plus } from "@element-plus/icons-vue";
import { post, get } from "@/utlis/http";
import Cookies from "js-cookie";
export default {
  setup() {
    return {
      Search,
      Plus,
    };
  },
  data() {
    return {
      loading: true, //加载
      //选择值的参数
      selectParameter: {
        status: undefined,
        type: undefined,
      },
      adTypeMap: [
        //广告类型
        { value: 1, unionTypes: [1, 2, 3, 4], picRequire: true, name: "轮播" },
        { value: 2, unionTypes: [2], picRequire: true, name: "分类精选" },
        { value: 3, unionTypes: [1, 2, 3, 4], picRequire: true, name: "横幅" },
        {
          value: 4,
          unionTypes: [1, 2, 3, 4],
          picRequire: true,
          name: "首页轮播下5按钮",
        },
        { value: 6, unionTypes: [1, 2, 3, 4], picRequire: false, name: "公告" },
        { value: 9, unionTypes: [1], picRequire: false, name: "商品推荐" },
      ],
      adUnionTypeMap: [
        //4种广告关联类型
        { value: 1, name: "商品" },
        { value: 2, name: "类目" },
        { value: 3, name: "关键字" },
        { value: 4, name: "功能页面" },
      ],
      adStatusMap: [
        //广告状态
        { value: 0, name: "冻结" },
        { value: 1, name: "激活" },
      ],
      functionPages: [
        { value: "/pages/product/groupshop", name: "团购列表" },
        { value: "/pages/coupon/list", name: "优惠券列表" },
      ],
      pages: {
        page: 1, //页
        limit: 10, //条
        total: 10, //总条数
      },
      advertisingData: [], //表格数据
      dialogVisible: false, //对话框
      title: "", //判断是添加还是编辑
      ruleForm: {
        type: "", //广告类型
        unionType: "", //关联类型
        title: "", //广告标题
        unionValue: "", //关联值
        imgUrl: "", //广告图片地址
        status: "", //广告状态
        color: "rgb(255,255,255)", //广告图片颜色
        adId: "",
      },
      imgUrl: "",
      headers: { AdminToken: Cookies.get("token") },
      rules: {
        // 添加表单验证
        title: [{ required: true, message: "请输入广告标题", trigger: "blur" }],
        type: [
          { required: true, message: "请选择广告类型", trigger: "change" },
        ],
        status: [
          { required: true, message: "请选择广告状态", trigger: "blur" },
        ],
        unionType: [
          { required: true, message: "请选择关联类型", trigger: "change" },
        ],
        unionValue: [
          {
            required: true,
            message: "请至少选择一个关联类型的类型",
            trigger: "change",
          },
        ],
      },
      imgShow: true, //上传图片的显示隐藏
      option: [], //商品选择
      options: [], //类目
      props: {
        value: "id", //指定选项的值为选项对象的某个属性值
        label: "label", //指定选项标签为选项对象的某个属性值
        children: "children", //指定选项的子选项为选项对象的某个属性值
        emitPath: false, //在选中节点改变时，是否返回由该节点所在的各级菜单的值所组成的数组，若设置 false，则只返回该节点的值
      },
    };
  },
  computed: {
    token() {
      let headers = { AdminToken: Cookies.get("token") };
      return headers;
    },
    //判断广告类型
    advertisingTypes() {
      return (type) => {
        for (const i of this.adTypeMap) {
          if (i.value == type) {
            return i.name;
          }
        }
      };
    },
    //判断关联类型
    associationTypes() {
      return (unionType) => {
        for (const i of this.adUnionTypeMap) {
          if (i.value == unionType) {
            return i.name;
          }
        }
      };
    },
  },
  created() {
    this.initiaLize();
  },
  watch: {
    //深度监听ruleForm对象
    ruleForm: {
      deep: true,
      handler(val) {
        let { type } = val;
        this.imgShow = type == 9 || type == 6 ? false : true;
        if (9 == type) {
          this.ruleForm.unionType = 1;
          this.adUnionTypeMap = [{ value: 2, name: "商品" }];
        } else if (2 == type) {
          this.ruleForm.unionType = 2;
          this.adUnionTypeMap = [{ value: 2, name: "类目" }];
        } else {
          this.adUnionTypeMap = [
            { value: 1, name: "商品" },
            { value: 2, name: "类目" },
            { value: 3, name: "关键字" },
            { value: 4, name: "功能页面" },
          ];
        }
      },
    },
  },
  methods: {
    //数据初始化
    initiaLize() {
      let data = {
        _gp: "admin.advert",
        _mt: "list",
        type: this.selectParameter.type,
        status: this.selectParameter.status,
        pageNo: this.pages.page,
        limit: this.pages.limit,
      };
      get(data).then((res) => {
        let { data, errno } = res.data;
        if (200 == errno) {
          this.loading = false;
          this.advertisingData = data.items;
          this.pages.total = data.total;
        }
      });
    },
    //商品和类目
    CommodityCategories() {
      //商品
      let data = {
        _gp: "admin.product",
        _mt: "getSpuBigTree",
      };
      post(data).then((res) => {
        let { data, errno } = res.data;
        if (200 == errno) {
          this.options = this.clearTree(JSON.parse(JSON.stringify(data))); //深度克隆，不影响原本数据
          this.option = data;
        }
      });
    },
    //清洗数据，只保留类目数据
    clearTree(data) {
      if (data == null || data === undefined) {
        return data;
      }
      //递归
      for (const i of data) {
        if (
          i.children.length === 0 ||
          i.children[0].value.indexOf("G_") != -1
        ) {
          //如果找到
          i.children = undefined;
        } else {
          //没找到就继续调用方法
          this.clearTree(i.children);
        }
      }
      //全部循环后需要return出去，不然会形成死循环
      return data;
    },
    //上传图片
    handleAvatarSuccess(file) {
      if (200 == file.errno) {
        this.ruleForm.imgUrl = file.url;
        const img = new Image();
        let canvas = this.$refs.canvas;
        img.src = file.url;
        img.src = `${file.url}?item=${new Date().getTime()}`;
        img.setAttribute("crossOrigin", "anonymous");
        img.onload = () => {
          let color = this.getImgColor(img, canvas);
          this.ruleForm.color = color;
        };
      }
    },
    getImgColor(img, canvas) {
      img.crossOrigin = "";
      canvas.width = img.width;
      canvas.height = img.height;
      let context = canvas.getContext("2d"); //<img> 标签
      context.drawImage(img, 0, 0);
      // 获取像素数据
      let data = context.getImageData(0, 0, img.width, img.height).data;
      let r = 0;
      let g = 0;
      let b = 0;
      // 取所有像素的平均值
      for (var row = 0; row < img.height; row++) {
        for (var col = 0; col < img.width; col++) {
          r += data[(img.width * row + col) * 4];
          g += data[(img.width * row + col) * 4 + 1];
          b += data[(img.width * row + col) * 4 + 2];
        }
      }

      // 求取平均值
      r = r / (img.width * img.height);
      g = g / (img.width * img.height);
      b = b / (img.width * img.height);

      // 将最终的值取整
      r = Math.round(r);
      g = Math.round(g);
      b = Math.round(b);
      return "rgb(" + r + "," + g + "," + b + ")";
    },
    //上传之前
    beforeAvatarUpload(rawFile) {
      if (rawFile.type !== "image/jpeg") {
        ElMessage.error("上传图片格式必须为jpg!");
        return false;
      } else if (rawFile.size / 1024 / 1024 > 2) {
        ElMessage.error("上传图片大小不能超过2MB!");
        return false;
      }
      return true;
    },
    //添加
    addAdvertising() {
      this.title = "创建";
      this.ruleForm.imgUrl = "";
      this.CommodityCategories();
      this.$nextTick(() => {
        this.$refs.ruleFormRef?.clearValidate();
      });
      this.dialogVisible = true;
    },
    //保存添加
    keepAdvertising(ruleFormRef) {
      let img = document.getElementsByClassName(
        "el-upload-list__item-thumbnail"
      )[0];
      let canvas = document.getElementById("canvas");
      this.$refs[ruleFormRef].validate((valid) => {
        if (valid == false) {
          return;
        } else {
          if (!this.ruleForm.imgUrl) {
            this.ruleForm.imgUrl =
              "http://img.zxwyit.com/admin.shopmall.com/137cd8fbe6fd427c89159eda4489428f.png";
          }
          let data = {
            _gp: "admin.advert",
            _mt: "create",
            ...this.ruleForm,
          };
          post(data).then((res) => {
            if (200 == res.data.errno) {
              ElMessage.success("创建成功");
              this.handleClose();
              this.dialogVisible = false;
              this.loading = true;
              this.initiaLize();
            }
          });
        }
      });
    },
    //编辑
    handleRedact(row) {
      this.imgUrl = row.imgUrl;
      this.ruleForm.adId = row.id;
      this.title = "编辑";
      Object.assign(this.ruleForm, row);
      if (this.ruleForm.unionType == 2 || this.ruleForm.unionType == 1) {
        this.ruleForm.unionValue = parseInt(row.unionValue);
      }
      this.CommodityCategories();
      this.dialogVisible = true;
    },
    //保存编辑
    redactdvertising(ruleFormRef) {
      this.$refs[ruleFormRef].validate((valid) => {
        if (valid == false) {
          return;
        } else {
          let data = {
            _gp: "admin.advert",
            _mt: "edit",
            ...this.ruleForm,
          };
          post(data).then((res) => {
            if (200 == res.data.errno) {
              ElMessage.success("修改成功");
              this.dialogVisible = false;
              this.loading = true;
              this.initiaLize();
            }
          });
        }
      });
    },
    //删除
    handleDelete(row) {
      ElMessageBox.confirm("确定删除?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          let data = {
            _gp: "admin.advert",
            _mt: "delete",
            type: row.type,
            adId: row.id,
          };
          post(data).then((res) => {
            if (200 == res.data.errno) {
              ElMessage.success("删除成功");
              this.initiaLize();
            }
          });
        })
        .catch(() => {
          ElMessage.info("已取消删除");
        });
    },
    //查找
    seekData() {
      this.initiaLize();
      this.loading = true;
    },
    //条
    changeLimit(val) {
      this.pages.limit = val;
      this.initiaLize();
    },
    //页
    changePage(val) {
      this.pages.page = val;
      this.initiaLize();
    },
    //关闭对话框
    handleClose() {
      this.ruleForm = {
        type: "", //广告类型
        unionType: "", //关联类型
        title: "", //广告标题
        unionValue: "", //关联值
        imgUrl: "", //广告图片地址
        status: 0, //广告状态
      };
      this.dialogVisible = false;
    },
  },
};
</script>

<style lang="less" scoped>
.el-table {
  margin: 20px 0px 40px 0;
  .el-image {
    width: 50px;
  }
}
</style>